use std::{path::PathBuf, sync::OnceLock};

use anyhow::bail;
use openssl::{
    pkey::{PKey, Private},
    x509::X509,
};

static LICENSE_PUBKEY: OnceLock<X509> = OnceLock::new();
static LICENSE_PRIKEY: OnceLock<PKey<Private>> = OnceLock::new();

pub async fn load_certificates(certificate_filename: &str) -> anyhow::Result<()> {
    let pubkey_file = PathBuf::from(".").join(format!("{}.pem", certificate_filename));
    if !pubkey_file.exists() {
        bail!("unable to load public key.");
    }
    let prikey_file = PathBuf::from(".").join(format!("{}.key", certificate_filename));
    if !prikey_file.exists() {
        bail!("unable to load private key.");
    }
    let pubkey = match cert_lib::load_certificate(pubkey_file) {
        Ok(cert) => cert,
        Err(e) => bail!("load certificate file failed: {}", e),
    };
    if let Err(_) = LICENSE_PUBKEY.set(pubkey) {
        bail!("unable to store public key.");
    }
    let prikey = match cert_lib::load_private_key(prikey_file) {
        Ok(key) => key,
        Err(e) => bail!("load private key file failed: {}", e),
    };
    if let Err(_) = LICENSE_PRIKEY.set(prikey) {
        bail!("unable to store private key.");
    }
    Ok(())
}

pub fn get_public_key() -> &'static X509 {
    LICENSE_PUBKEY.get().unwrap()
}

pub fn get_private_key() -> &'static PKey<Private> {
    LICENSE_PRIKEY.get().unwrap()
}
